package coreBiz

import (
	"bytes"
	"crypto/aes"
	"encoding/base64"
	"errors"
	"strings"
)

type AesEcb128 struct {
	Key []byte
}

func InitEncryptAesWithKeyIv(Key string) *AesEcb128 {
	return &AesEcb128{
		Key: []byte(Key),
	}
}

// EncryptECB 加密函数
func (a *AesEcb128) EncryptECB(content string) (string, error) {
	// 输入验证
	if len(content) == 0 {
		return "", errors.New("content cannot be empty")
	}
	if len(a.Key) != 16 {
		return "", errors.New("key length must be 16 bytes")
	}

	// 创建 AES 块加密器
	block, err := aes.NewCipher(a.Key)
	if err != nil {
		return "", err
	}

	// PKCS7 填充
	paddedContent := PKCS7Padding([]byte(content), block.BlockSize())

	// 使用 ECB 模式加密
	encrypted := make([]byte, len(paddedContent))
	bs := block.BlockSize()
	for start := 0; start < len(paddedContent); start += bs {
		block.Encrypt(encrypted[start:start+bs], paddedContent[start:start+bs])
	}

	// 将加密后的数据进行 base64 编码
	encoded := base64.StdEncoding.EncodeToString(encrypted)

	return encoded, nil
}

// DecryptECB 解密
func (a *AesEcb128) DecryptECB(content string) (string, error) {
	// 输入验证
	if len(content) == 0 {
		return "", errors.New("content cannot be empty")
	}
	if len(a.Key) != 16 {
		return "", errors.New("key length must be 16 bytes")
	}
	// 解析 base64 编码的加密字符串
	encrypted, err := base64.StdEncoding.DecodeString(content)
	if err != nil {
		return "", err
	}

	// 创建 AES 块加密器
	block, err := aes.NewCipher(a.Key)
	if err != nil {
		return "", err
	}

	if len(encrypted)%aes.BlockSize != 0 {
		return "", errors.New("encrypted data length must be a multiple of block size")
	}

	// 使用 ECB 模式解密
	decrypted := make([]byte, len(encrypted))
	bs := block.BlockSize()
	for start := 0; start < len(encrypted); start += bs {
		block.Decrypt(decrypted[start:start+bs], encrypted[start:start+bs])
	}

	// 去除 PKCS7 填充
	decrypted, err = PKCS7UnPadding(decrypted)
	if err != nil {
		return "", err
	}

	// 替换 '(null)' 字符串为空字符串
	decryptedStr := strings.ReplaceAll(string(decrypted), "(null)", "")

	return decryptedStr, nil
}

// PKCS7Padding 对数据进行 PKCS7 填充
func PKCS7Padding(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

// PKCS7UnPadding 去除 PKCS7 填充
func PKCS7UnPadding(data []byte) ([]byte, error) {
	length := len(data)
	if length == 0 {
		return nil, errors.New("data is empty")
	}
	paddingLength := int(data[length-1])
	if paddingLength > length {
		return nil, errors.New("padding length is invalid")
	}
	return data[:length-paddingLength], nil
}
